package com.srmt.feishu.client.exception;

/**
 * 飞书API调用异常
 *
 * <p>封装飞书API返回的错误码和错误消息，用于统一异常处理。
 * 支持识别速率限制相关的错误（429、99991400），以便重试装饰器能够正确处理。</p>
 *
 * <h3>使用场景：</h3>
 * <ul>
 *   <li>HTTP状态码非200时抛出</li>
 *   <li>飞书API返回错误码（code != 0）时抛出</li>
 *   <li>可以通过 {@link #isRateLimitError()} 判断是否为限流错误</li>
 * </ul>
 *
 * <h3>示例：</h3>
 * <pre>{@code
 * if (response.getStatusCode() != 200) {
 *     throw new FeishuApiException("getValues",
 *         response.getStatusCode(),
 *         "HTTP请求失败");
 * }
 *
 * if (code != 0) {
 *     throw new FeishuApiException("updateValues",
 *         code,
 *         errorMessage);
 * }
 * }</pre>
 *
 * @author SRMT Development Team
 * @since 2.0.0
 */
public class FeishuApiException extends RuntimeException {

    /**
     * 错误码（可能是HTTP状态码或飞书API错误码）
     */
    private final int code;

    /**
     * API操作名称
     */
    private final String apiOperation;

    /**
     * 构造函数 - 用于API错误码
     *
     * @param apiOperation API操作名称（如 "getValues", "updateValues"）
     * @param code 错误码（飞书API返回的code字段）
     * @param message 错误消息（飞书API返回的msg字段）
     */
    public FeishuApiException(String apiOperation, int code, String message) {
        super(String.format("API %s 调用失败: %s (错误码: %d)", apiOperation, message, code));
        this.code = code;
        this.apiOperation = apiOperation;
    }

    /**
     * 构造函数 - 用于HTTP错误
     *
     * @param apiOperation API操作名称
     * @param httpStatus HTTP状态码
     * @param message 错误消息
     * @param cause 原始异常
     */
    public FeishuApiException(String apiOperation, int httpStatus, String message, Throwable cause) {
        super(String.format("API %s 调用失败,HTTP状态码 %d: %s", apiOperation, httpStatus, message), cause);
        this.code = httpStatus;
        this.apiOperation = apiOperation;
    }

    /**
     * 获取错误码
     *
     * @return 错误码（HTTP状态码或飞书API错误码）
     */
    public int getCode() {
        return code;
    }

    /**
     * 获取API操作名称
     *
     * @return API操作名称
     */
    public String getApiOperation() {
        return apiOperation;
    }

    /**
     * 判断是否为速率限制错误
     *
     * <p>识别以下错误码：</p>
     * <ul>
     *   <li>429 - HTTP标准的Too Many Requests</li>
     *   <li>99991400 - 飞书特定的频率限制错误码</li>
     * </ul>
     *
     * @return 如果是速率限制错误返回true
     */
    public boolean isRateLimitError() {
        return code == 429 || code == 99991400 || getMessage().contains("429");
    }
}
